package com.gitee.huanminabc.fastboot.load.stage.syncstage;
import com.gitee.huanminabc.jcommon.reflect.ClassScanner;
import com.gitee.huanminabc.jcommon.reflect.ClassUtil;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.context.AppContextUtil;
import com.gitee.huanminabc.fastboot.load.hook.LifecycleHook;
import com.gitee.huanminabc.fastboot.load.hook.ProjectClassLoadFinishLifecycleHook;
import com.gitee.huanminabc.fastboot.load.classload.ClassLoadIntercept;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Modifier;
import java.util.Set;

/**
 * @description: 项目类加载阶段
 * @author: huanmin
 * @create: 2025-04-01 10:55
 **/
@Slf4j
public class ProjectClassLoadStage implements AppLoadSyncStage {
    @Override
    public void run() {
        //类加载拦截器排序
        AppContextUtil.orderSort(AppContext.classLoadIntercepts);
        try {
            //获取类的包
            String packageName = AppContext.mainClass.getPackage().getName();
            //获取类下的全部类
            Set<Class<?>> classes = ClassScanner.scanPackGetClasses(packageName);
            for (Class<?> aClass : classes) {
                //过滤掉抽象类,注解,枚举类 ,或者是非public的类
                if (aClass.isEnum() ||
                        //接口
                        aClass.isInterface() ||
                        //注解跳过
                        aClass.isAnnotation() ||
                        //内部类跳过
                        aClass.isMemberClass() ||
                        //抽象类跳过
                        Modifier.isAbstract(aClass.getModifiers()) ||
                        //非public跳过
                        !Modifier.isPublic(aClass.getModifiers())
                ) {
                    continue;
                }
                //这个是必须的, 因为AOP需要全部类看看哪一个需要代理
                AppContext.allClasses.add(aClass);
                //类加载拦截器
                for (ClassLoadIntercept classLoadIntercept : AppContext.classLoadIntercepts) {
                    classLoadIntercept.peek(aClass);
                    Class<?> replace = classLoadIntercept.replace(aClass);
                    if (replace != null) {
                        aClass = replace;
                    }
                }
            }
            log.debug("ProjectClassLoadStage: [{}]  load success", AppContext.allClasses.size());
            //运行类加载完成的钩子
            new ProjectClassLoadFinishLifecycleHook().run();
        } catch (Exception e) {
            log.error("ProjectClassLoadStage load error", e);
            System.exit(1);
        }
    }


}
